#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
API批量提交工具
专门用于将已爬取的商品数据提交到后端的批量处理接口
"""

import json
import time
import requests
import logging
from typing import List, Dict, Any, Optional
from datetime import datetime
from pathlib import Path

# 导入API配置
from api_config import APIConfig

# 设置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('api_batch_submit.log', encoding='utf-8'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

class APIBatchSubmitter:
    """API批量提交器"""
    
    def __init__(self):
        """初始化提交器"""
        self.api_url = APIConfig.get_products_api_url()
        self.headers = APIConfig.DEFAULT_HEADERS.copy()
        self.session = requests.Session()
        
        logger.info(f"🔧 API批量提交器初始化完成")
        logger.info(f"🌐 目标API: {self.api_url}")
    
    def submit_products_batch(self, products: List[Dict[str, Any]], store_id: str, platform: str) -> bool:
        """
        批量提交商品数据到新的处理接口
        
        Args:
            products: 商品数据列表 (API格式)
            store_id: 店铺ID
            platform: 平台名称
            
        Returns:
            bool: 提交是否成功
        """
        try:
            # 构建批量提交的数据格式
            payload = {
                "store_id": store_id,
                "platform": APIConfig.PLATFORM_MAPPING.get(platform, platform),
                "products": products,
                "batch_info": {
                    "total_products": len(products),
                    "timestamp": datetime.now().isoformat(),
                    "source": "scraper_batch_submit"
                }
            }
            
            if APIConfig.ENABLE_REQUEST_LOGGING:
                logger.info(f"📦 准备提交批量数据:")
                logger.info(f"   🏪 Store ID: {store_id}")
                logger.info(f"   🏷️  Platform: {payload['platform']}")
                logger.info(f"   📊 商品数量: {len(products)}")
                logger.info(f"   🌐 API地址: {self.api_url}")
            
            # 发送请求（支持重试）
            for attempt in range(APIConfig.MAX_RETRIES):
                try:
                    if APIConfig.ENABLE_VERBOSE_LOGGING:
                        logger.info(f"🔄 第 {attempt + 1}/{APIConfig.MAX_RETRIES} 次尝试提交...")
                    
                    response = self.session.post(
                        self.api_url,
                        json=payload,
                        headers=self.headers,
                        timeout=APIConfig.REQUEST_TIMEOUT
                    )
                    
                    if APIConfig.ENABLE_RESPONSE_LOGGING:
                        logger.info(f"📡 API响应状态码: {response.status_code}")
                        if response.text:
                            logger.info(f"📄 API响应内容: {response.text[:500]}...")
                    
                    if response.status_code == 200:
                        logger.info(f"✅ 批量提交成功: {len(products)} 个商品")
                        return True
                    else:
                        error_msg = f"API返回错误状态码: {response.status_code}"
                        if response.text:
                            error_msg += f" - {response.text}"
                        
                        if attempt < APIConfig.MAX_RETRIES - 1:
                            logger.warning(f"⚠️ {error_msg}，{APIConfig.RETRY_DELAY}秒后重试...")
                            time.sleep(APIConfig.RETRY_DELAY)
                        else:
                            logger.error(f"❌ 批量提交失败: {error_msg}")
                            return False
                            
                except requests.RequestException as e:
                    error_msg = f"网络请求异常: {e}"
                    if attempt < APIConfig.MAX_RETRIES - 1:
                        logger.warning(f"⚠️ {error_msg}，{APIConfig.RETRY_DELAY}秒后重试...")
                        time.sleep(APIConfig.RETRY_DELAY)
                    else:
                        logger.error(f"❌ 批量提交失败: {error_msg}")
                        return False
            
            return False
            
        except Exception as e:
            logger.error(f"❌ 批量提交异常: {e}")
            return False
    
    def submit_from_file(self, file_path: str, store_id: str, platform: str) -> bool:
        """
        从文件读取商品数据并提交
        
        Args:
            file_path: 商品数据文件路径
            store_id: 店铺ID
            platform: 平台名称
            
        Returns:
            bool: 提交是否成功
        """
        try:
            file_path = Path(file_path)
            if not file_path.exists():
                logger.error(f"❌ 文件不存在: {file_path}")
                return False
            
            logger.info(f"📂 读取商品数据文件: {file_path}")
            
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
            
            # 处理不同的文件格式
            products = []
            if isinstance(data, list):
                # 直接是商品列表
                products = data
            elif isinstance(data, dict):
                if 'products' in data:
                    # 包含products字段的格式
                    products = data['products']
                else:
                    # 单个商品对象
                    products = [data]
            
            if not products:
                logger.error("❌ 文件中没有找到商品数据")
                return False
            
            logger.info(f"📦 从文件读取到 {len(products)} 个商品")
            
            # 提交数据
            return self.submit_products_batch(products, store_id, platform)
            
        except Exception as e:
            logger.error(f"❌ 从文件提交失败: {e}")
            return False
    
    def submit_from_multiple_files(self, file_paths: List[str], store_id: str, platform: str) -> bool:
        """
        从多个文件读取商品数据并合并提交
        
        Args:
            file_paths: 商品数据文件路径列表
            store_id: 店铺ID
            platform: 平台名称
            
        Returns:
            bool: 提交是否成功
        """
        try:
            all_products = []
            
            for file_path in file_paths:
                file_path = Path(file_path)
                if not file_path.exists():
                    logger.warning(f"⚠️ 文件不存在，跳过: {file_path}")
                    continue
                
                logger.info(f"📂 读取文件: {file_path}")
                
                with open(file_path, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                
                # 处理不同的文件格式
                file_products = []
                if isinstance(data, list):
                    file_products = data
                elif isinstance(data, dict):
                    if 'products' in data:
                        file_products = data['products']
                    else:
                        file_products = [data]
                
                all_products.extend(file_products)
                logger.info(f"✅ 从 {file_path.name} 读取到 {len(file_products)} 个商品")
            
            if not all_products:
                logger.error("❌ 所有文件中都没有找到商品数据")
                return False
            
            logger.info(f"📦 总共合并了 {len(all_products)} 个商品")
            
            # 提交合并后的数据
            return self.submit_products_batch(all_products, store_id, platform)
            
        except Exception as e:
            logger.error(f"❌ 从多个文件提交失败: {e}")
            return False

def submit_pdd_data(file_path: str, store_id: Optional[str] = None) -> bool:
    """
    快捷方法：提交PDD商品数据
    
    Args:
        file_path: PDD商品数据文件路径
        store_id: 店铺ID (可选，如果不提供会尝试从文件名或数据中提取)
        
    Returns:
        bool: 提交是否成功
    """
    submitter = APIBatchSubmitter()
    
    # 如果没有提供store_id，尝试生成一个
    if not store_id:
        store_id = f"pdd_store_{int(time.time())}"
        logger.info(f"🆔 自动生成Store ID: {store_id}")
    
    return submitter.submit_from_file(file_path, store_id, "拼多多")

def submit_jd_data(file_path: str, store_id: Optional[str] = None) -> bool:
    """
    快捷方法：提交JD商品数据
    
    Args:
        file_path: JD商品数据文件路径
        store_id: 店铺ID (可选)
        
    Returns:
        bool: 提交是否成功
    """
    submitter = APIBatchSubmitter()
    
    if not store_id:
        store_id = f"jd_store_{int(time.time())}"
        logger.info(f"🆔 自动生成Store ID: {store_id}")
    
    return submitter.submit_from_file(file_path, store_id, "京东")

def submit_taobao_data(file_path: str, store_id: Optional[str] = None) -> bool:
    """
    快捷方法：提交淘宝商品数据
    
    Args:
        file_path: 淘宝商品数据文件路径
        store_id: 店铺ID (可选)
        
    Returns:
        bool: 提交是否成功
    """
    submitter = APIBatchSubmitter()
    
    if not store_id:
        store_id = f"taobao_store_{int(time.time())}"
        logger.info(f"🆔 自动生成Store ID: {store_id}")
    
    return submitter.submit_from_file(file_path, store_id, "淘宝")

def submit_dy_data(file_path: str, store_id: Optional[str] = None) -> bool:
    """
    快捷方法：提交抖音商品数据
    
    Args:
        file_path: 抖音商品数据文件路径
        store_id: 店铺ID (可选)
        
    Returns:
        bool: 提交是否成功
    """
    submitter = APIBatchSubmitter()
    
    if not store_id:
        store_id = f"dy_store_{int(time.time())}"
        logger.info(f"🆔 自动生成Store ID: {store_id}")
    
    return submitter.submit_from_file(file_path, store_id, "抖音")

def main():
    """主函数 - 交互式提交工具"""
    print("🚀 API批量提交工具")
    print("="*60)
    
    # 显示当前API配置
    APIConfig.print_config()
    
    if not APIConfig.validate_config():
        print("❌ API配置验证失败，请检查配置")
        return
    
    submitter = APIBatchSubmitter()
    
    while True:
        print("\n请选择操作:")
        print("1. 提交PDD商品数据")
        print("2. 提交JD商品数据")
        print("3. 提交淘宝商品数据")
        print("4. 提交抖音商品数据")
        print("5. 自定义提交")
        print("6. 批量提交多个文件")
        print("7. 退出")
        
        choice = input("\n请输入选择 (1-7): ").strip()
        
        if choice == '1':
            file_path = input("请输入PDD商品数据文件路径: ").strip()
            store_id = input("请输入Store ID (回车使用自动生成): ").strip()
            
            if submit_pdd_data(file_path, store_id if store_id else None):
                print("✅ PDD数据提交成功")
            else:
                print("❌ PDD数据提交失败")
                
        elif choice == '2':
            file_path = input("请输入JD商品数据文件路径: ").strip()
            store_id = input("请输入Store ID (回车使用自动生成): ").strip()
            
            if submit_jd_data(file_path, store_id if store_id else None):
                print("✅ JD数据提交成功")
            else:
                print("❌ JD数据提交失败")
                
        elif choice == '3':
            file_path = input("请输入淘宝商品数据文件路径: ").strip()
            store_id = input("请输入Store ID (回车使用自动生成): ").strip()
            
            if submit_taobao_data(file_path, store_id if store_id else None):
                print("✅ 淘宝数据提交成功")
            else:
                print("❌ 淘宝数据提交失败")
                
        elif choice == '4':
            file_path = input("请输入抖音商品数据文件路径: ").strip()
            store_id = input("请输入Store ID (回车使用自动生成): ").strip()
            
            if submit_dy_data(file_path, store_id if store_id else None):
                print("✅ 抖音数据提交成功")
            else:
                print("❌ 抖音数据提交失败")
                
        elif choice == '5':
            file_path = input("请输入商品数据文件路径: ").strip()
            store_id = input("请输入Store ID: ").strip()
            platform = input("请输入平台名称 (拼多多/京东/淘宝/抖音): ").strip()
            
            if submitter.submit_from_file(file_path, store_id, platform):
                print("✅ 自定义数据提交成功")
            else:
                print("❌ 自定义数据提交失败")
                
        elif choice == '6':
            file_paths_input = input("请输入多个文件路径 (用逗号分隔): ").strip()
            file_paths = [path.strip() for path in file_paths_input.split(',')]
            store_id = input("请输入Store ID: ").strip()
            platform = input("请输入平台名称 (拼多多/京东/淘宝/抖音): ").strip()
            
            if submitter.submit_from_multiple_files(file_paths, store_id, platform):
                print("✅ 批量文件提交成功")
            else:
                print("❌ 批量文件提交失败")
                
        elif choice == '7':
            print("👋 再见！")
            break
        else:
            print("❌ 无效选择，请重试")

if __name__ == "__main__":
    main() 